#ifndef SPL_TOOLBAR
#define SPL_TOOLBAR

#define TOOLITEMMASK_STATIC 0x00010000
#define TOOLITEMMASK_MENU   0x00100000

#define TOOLITEM_NORMAL     0x00
#define TOOLITEM_CHECKED    0x01
#define TOOLITEM_DISABLED   0x02
#define TOOLITEM_AUTORENAME 0x08

#define TOOLBAR_HEIGHT      24
#define TOOLBAR_MAXTEXT     100

enum ToolItemType
{
  ToolItemInvalid       = 0x00000000,

  ToolItemLabel         = 0x00010001,
  ToolItemSeparator     = 0x00010002,
  ToolItemSpace         = 0x00010003,
  ToolItemBreak         = 0x00010004,

  ToolItemMenu          = 0x00100001,
  ToolItemButtonMenu    = 0x00100002,

  ToolItemEdit          = 0x00000001,
  ToolItemNumeric       = 0x00000002,
  ToolItemButton        = 0x00000003,
};

struct ToolItem
{
  INT             nID;
  TCHAR           szText[TOOLBAR_MAXTEXT + 1];
  ToolItemType    type;
  VOID*           typeData;
  INT             size;
  INT             state;
  VOID*           userData;
};

struct ItemDataNumeric
{
  INT             min;
  INT             max;
  INT             inc;
  INT             pos;
};

enum ItemPart
{
  ItemPartContent,
  ItemPartMenu,
  ItemPartMenuItem,
  ItemPartEdit,
};

struct ToolBarNotify : NMHDR
{
  INT             itemID;
  ItemPart        itemPart;
  INT             value;
};

class DLLEXPORT ToolBar : public Control
{
private:
  struct ToolBarItem : ToolItem
  {
    Gdip::RectF   bounds;
    HWND          window;
    INT           flags;
  };

  Generic::Vector<ToolBarItem*, 5> mItems;

  INT         itemOvered;
  INT         itemPressed;
  ItemPart    itemPart;

  HFONT       font;
  COLORREF    backColor;

  VOID        drawItem(
    Gdip::Graphics &g,
    INT index);
  VOID        drawItemBackground(
    Gdip::Graphics &g,
    INT index);
  VOID        drawItemPart(
    Gdip::Graphics &g,
    Gdip::RectF &bounds,
    INT index,
    ItemPart part);

  VOID        measureItems(INT startIndex);
  VOID        positionItems(INT startIndex);
  VOID        positionItem(UINT iIndex, Gdip::PointF &pos);
  VOID        invalidateItem(INT index);
  VOID        freeItem(ToolBarItem* item);

  VOID        doAction();
  VOID        hitTestItem(POINT& pt);

  VOID        setStringFormat(Gdip::StringFormat &format);
  VOID        getItemShape(
    Gdip::GraphicsPath  &path,
    const Gdip::RectF   &bounds,
    INT                 flags);

protected:
  virtual VOID onCreate(Event::WndCreateEvent&);
  virtual VOID onDestroy();
  virtual VOID onMouseMove(Event::MouseEvent&);
  virtual VOID onMouseLeave();
  virtual VOID onMouseDown(Event::MouseEvent&);
  virtual VOID onMouseUp(Event::MouseEvent&);
  virtual VOID onKeyDown(Event::KeyEvent&);
  virtual VOID onNotify(Event::NotifyEvent&);
  virtual VOID onEraseBackground(Event::EraseBackgroundEvent&);
  virtual VOID onControlPaint(Controls::ControlPaintEvent& iEvent);
  virtual VOID onSetFocus(Event::FocusEvent&);
  virtual VOID onKillFocus(Event::FocusEvent&);
  virtual VOID onSize(Event::SizeEvent&);

public:
  VOID        addItems(ToolItem *pItems, UINT count = 1);
  VOID        addItem(PTCHAR szText, PTCHAR szInfo, ToolItemType type);
  BOOL        removeItems(UINT index, UINT count = 1);
  SPLINL BOOL clearItems()
  {
    itemOvered  = -1;
    itemPressed = -1;
    return removeItems(0, mItems.getLength());
  }

  VOID        setItemText(PCTSTR szText, INT nID);
  VOID        setItemState(INT state, INT nID);
  INT         getItemState(INT nID);

  VOID        getItemBounds(INT nID, Geom::Bounds& bounds);

  INT         selectPrevItem(INT iIndex = -1);
  INT         selectNextItem(INT iIndex = -1);

  const ToolItem* getItem(UINT iIndex)
  {
    return mItems.get(iIndex);
  }

  const ToolItem* getItemFromID(INT iID);

  BOOL        getItems(ToolItem *pItems, UINT index, UINT count = 1);
  SPLINL INT  getItemCount()
  {
    return mItems.getLength();
  }

  VOID        setItemChecked(INT nID, BOOL checked);
  BOOL        getItemChecked(INT nID);

  COLORREF    getBackColor()
  {
    return backColor;
  }
  VOID        setBackColor(COLORREF value)
  {
    backColor = value;
  }

  ToolBar();
};

#endif